window.SearchSpringInit = function() { var self = this; if (self.context.collectionHandle && typeof self.context.collectionHandle == 'string') { // Set background filter if (self.context.collectionHandle != 'all') { self.context.backgroundFilters.collection_handle = self.context.collectionHandle; } // Handle collection tags (filters) if (self.context.tags && typeof self.context.tags == 'string') { var collectionTags = self.context.tags.toLowerCase().replace(/\"\;/g, '"').replace(/-/g, '').replace(/ +/g, '').split('|'); self.context.backgroundFilters.ss_tags = collectionTags; } } // springboard generated variables var modules = {}; modules.enabled = true; // springboard generated variables for autocomplete/default modules['autocomplete'] = { input: '.search-header__input', spellCorrection: false, language: 'en', action: '', autoPosition: false, limit: 6 }; this.importer.include('autocomplete2', modules.autocomplete); this.on('afterSearch', function($scope) { angular.forEach($scope.facets, function(facet) { // Create different limits for different facet types // For palette and grid types, this makes sure boxes fill the last row var facetType = (facet.type == 'palette' || facet.type == 'grid') ? true : false; facet.limitCount = facetType ? 16 : 12; }); }); this.importer.include('infinite'); this.on('afterSearch', function($scope) { // Check if there is more than one page (for head title logic) $scope.pagination.multiplePages = true; if ($scope.pagination.totalResults <= $scope.pagination.perPage) { $scope.pagination.multiplePages = false; } // Set default image url $scope.results.defaultImage = '//cdn.searchspring.net/ajax_search/img/default_image.png'; angular.forEach($scope.results, function(result) { // If no thumbnail image, set default image if (!result.thumbnailImageUrl) { result.thumbnailImageUrl = $scope.results.defaultImage; } // Pre-load images and check for loading errors var ssResultsImage = new Image(); ssResultsImage.src = result.thumbnailImageUrl; // If image errors, load default image instead ssResultsImage.onerror = function() { result.thumbnailImageUrl = $scope.results.defaultImage; $scope.$evalAsync(); } result.quickview = false; result.quickviewHtml = false; }); }); this.on('afterSearch', function ($scope) { // Create loop for rating stars angular.forEach($scope.results, function(result) { result.stars_array = []; // loop through 5 times (5 stars) for (var i = 1; i < 6; i++) { if (i <= result.rating) { result.stars_array.push(''); } else { result.stars_array.push('-o'); } } }); }); //In an afterSearch callback, set the swatch limit and define our swapImg function. this.on('afterSearch', function($scope) { $scope.limit = 6; }); // --- START CONTENT TAB LOGIC // Create tabs object var tabs = { default : 'todos', location : '', current : 'todos', previous : 'todos', values : [ { label : 'Todos', name : 'todos', siteid : 'acdtnn', order : 1, class : 'ss-has-todos', beforeSearch : function(req) { // Delete previous bgfilters if (req && req['bgfilter.ss_type']) { delete req['bgfilter.ss_type']; } } }, { label : 'Productos', name : 'productos', siteid : 'acdtnn', order : 2, class : 'ss-has-productos', beforeSearch : function(req) { // Delete previous bgfilters if (req && req['bgfilter.ss_type']) { delete req['bgfilter.ss_type']; } req['bgfilter.ss_type'] = 'Producto'; } }, { label : 'Proyectos', name : 'proyectos', siteid : 'acdtnn', order : 3, class : 'ss-has-proyectos', beforeSearch : function(req) { // Delete previous bgfilters if (req && req['bgfilter.ss_type']) { delete req['bgfilter.ss_type']; } req['bgfilter.ss_type'] = 'Proyecto'; } } ], getTab : function(name) { var tab = this.values.filter(function(tab) { return tab.name == name; }).pop(); return tab; } }; this.on('afterBootstrap', function($scope) { // Update tab location and set tabs to scope tabs.location = $scope.location; $scope.tabs = tabs; // Update tab details when the tab is switched $scope.tabs.changeTab = function(name) { // Getting the tab with the name that's passed in var tab = tabs.getTab(name); // Check if there are tabs if (tab) { // Change search results tab information this.previous = this.current; this.current = name; if (this.current != this.previous) { // Reset location and remove filters if tabs have changes var resultsLocation = $scope.location().remove('results').remove('sort').remove('page').remove('filter'); resultsLocation = (this.current != 'todos') ? resultsLocation.add('results', name) : resultsLocation; resultsLocation.go(); // Reset search form and results swapTabClasses(name); updateSearchForms(name); $scope.results = []; } } }; }); this.on('afterBootstrap', function($scope) { self.on('beforeSearch', function(req, config) { if (config.moduleName == 'autocomplete2') { return; } // Set resultsTabName to tabs.default var resultsTabName = tabs.default; // Get location of the result set var resultSet = tabs.location().get('results'); // If there is a hash, use it to change resultsTabName if (resultSet.length && resultSet[0][1] && (resultSet[0][1] != tabs.default)) { resultsTabName = resultSet[0][1]; } // Update results and autocomplete current tab tabs.current = resultsTabName; // Get the tab with the name equal to resultsTabName var tab = tabs.getTab(resultsTabName); // If there's a tab, update details if (tab) { tab.beforeSearch(req); swapTabClasses(tab.name); updateSearchForms(tab.name); } }); }); // Update the form action depending on what tab is selected function updateSearchForms(tabName) { // Change the action on the actual search form var searchInputs = angular.element(document.querySelectorAll('.search-header__input')); if (searchInputs && searchInputs.length) { for (var i = 0; i < searchInputs.length; i++) { var searchForm = angular.element(searchInputs[i].form); if (searchForm && searchForm.length) { var resultsParam = '#results:'; var searchFormAction = (searchForm.attr('action').split(resultsParam)[0]) + (tabName != 'todos' ? '' : (resultsParam + tabName)); searchForm.attr('action', searchFormAction); } } } } // Add classes for tabs function swapTabClasses(tabName) { var bodySelector = angular.element(document.querySelectorAll('body')[0]); if (bodySelector && bodySelector.length) { var tabValues = tabs.values; for (var tab in tabValues) { var currentTab = tabValues[tab]; if (currentTab.name == tabName) { bodySelector.addClass(currentTab.class); } else { bodySelector.removeClass(currentTab.class); } } } } // --- END CONTENT TAB LOGIC this.on('afterSearch', function($scope) { // Add inline merchandising banners if ($scope.pagination.totalResults && $scope.merchandising.content.inline) { // Variables for banner positions beyond pagination index var tailBanners = []; var bannerBegin = $scope.pagination.begin - 1; var bannerEnd = $scope.pagination.end; $scope.merchandising.content.inline.sort(function(a, b) { return a.config.position.index - b.config.position.index; }).filter(function(banner) { var index = banner.config.position.index; if (index >= bannerBegin) { if (index <= bannerEnd - 1) { return true; } else { tailBanners.push(bannerToResult(banner)); } } }).map(function(banner) { var adjustedIndex = $scope.infinite ? banner.config.position.index : (banner.config.position.index - bannerBegin); $scope.results.splice(adjustedIndex, 0, bannerToResult(banner)); }); var missingBegin = $scope.infinite ? 0 : bannerBegin; var totalResults = Math.min($scope.pagination.totalResults, bannerEnd); var missingResults = totalResults - (missingBegin + $scope.results.length); if (missingResults) { var sliceStart = ($scope.pagination.nextPage == 0) ? (tailBanners.length - missingResults) : 0; var missingBanners = tailBanners.slice(sliceStart, sliceStart + missingResults); angular.forEach(missingBanners, function(missingBanner) { $scope.results.push(missingBanner); }); } } }); function bannerToResult(banner) { return { uid : 'ssib-' + banner.config.position.index, isInlineBanner : true, content : banner.value } } // -- START -- DYNAMIC IMAGE LOGIC var colorFilters = []; var variantCache = {}; var swapVariants = function(result, variant) { result.thumbnailImageUrl = variant.image; if (variant.color) { // Update other variables } result.selectedVariant = variant; }; this.on('afterBootstrap', function($scope) { $scope.swapVariants = swapVariants; }); this.on('beforeSearch', function($req) { // Add selected colors to color filters array colorFilters = $req['filter.variant_mfield_global_color']; // If color filters is present, join and toLowerCase if (colorFilters) { colorFilters = colorFilters.join('|').toLowerCase().split('|'); } }); this.on('afterSearch', function($scope) { // Loop through results for colors angular.forEach($scope.results, function(result) { // Check if there are extra images available if (result.ss_swatches) { try { // Parse out the JSON for variant goodness if (!variantCache[result.id]) { variantCache[result.id] = JSON.parse(result.ss_swatches); } result.ss_swatches = angular.copy(variantCache[result.id]); if (result.ss_swatches.length) { var colorSearch; // Loop through the variants for (var i = 0; i < result.ss_swatches.length; i++) { var variant = result.ss_swatches[i]; // Variant.weight = tally of matched terms variant.weight = 0; // Set the simple and group color through the variant object var simpleColor = variant.label ? variant.label.toLowerCase() : ''; var groupColors; if (variant.family) { if (Array.isArray(variant.family)) { groupColors = variant.family.map(function(color) { return color.toLowerCase(); }); } else if (variant.family) { groupColors = [variant.family.toLowerCase()]; } } else { groupColors = ''; } // Check selected color filter matches angular.forEach(colorFilters, function(color, i) { var multiplier = (i + 1); // Check simple color and group color to see if there is a color match if ((simpleColor && simpleColor == color) || (simpleColor.indexOf(color) != -1)) { variant.weight += (10 * multiplier); } else if (groupColors.length) { angular.forEach(groupColors, function(groupColor) { if (groupColor == color || (groupColor.indexOf(color) != -1)) { variant.weight += (5 * multiplier); } }); } }); // Check search terms also if ($scope.q) { var terms = $scope.q.toLowerCase().split(' '); var simpleColors = simpleColor.replace('/', ' ').split(' '); angular.forEach(terms, function(term, i) { var multiplier = (i + 1); angular.forEach(simpleColors, function(simpleColor) { if (term == simpleColor || (simpleColor.indexOf(term) != -1)) { variant.weight += (1 * multiplier); colorSearch = true; } }); angular.forEach(groupColors, function(groupColor) { if (term == groupColor || (groupColor.indexOf(term) != -1)) { variant.weight += (1 * multiplier); colorSearch = true; } }); }); } } if (colorFilters || colorSearch) { // Find greatest weight in queried variants and select it! result.ss_swatches.sort(function(a, b) { return b.weight - a.weight; }); } // Use the first element in array (highest weight) swapVariants(result, result.ss_swatches[0]); } } catch (error) { // nope } } }); }); // -- END -- DYNAMIC IMAGE LOGIC this.on('afterBootstrap', function($scope) { $scope.quickview = $scope.quickview || {}; // QuickView functionality for modal $scope.quickview.modal = { active : false, create : function() { // Add QuickView modal div var qvID = 'searchspring-quickview-modal'; var qvContainer = document.getElementById(qvID); if (!qvContainer && !$scope.moduleName) { angular.element(document.querySelector('body')).append('
'); } }, show : function(ev, result) { ev.stopPropagation(); if (!$scope.quickview.modal.active) { addJsonData(result); self.utils.ensure(function() { return result.quickview; }, function() { $scope.quickview.modal.active = true; $scope.quickview.result = result; $scope.$evalAsync(); }); } else { // Close modal and reset result data $scope.quickview.modal.active = false; $scope.quickview.result = {}; } } } // Add QuickView modal $scope.quickview.modal.create(); }); // springboard generated variables for slideout/default modules['slideout'] = { width: 767 }; this.importer.include('slideout', modules.slideout); this.on('afterBootstrap', function($scope) { $scope.utilities = $scope.utilities || {}; // Helper function to find ancestors / parents... e = element, c = class if ($scope.utilities) { $scope.utilities.findAncestor = function(e, c) { while (e) { if (e.className && e.className.indexOf(c) !== -1) { return e; } e = e.parentNode; } return null; }; // Dropdown object with toggle functionality $scope.utilities.dropdown = { expandedClass : 'ss-expanded', dropdownClass : 'ss-dropdown-menu', removeClasses : function() { angular.element(document.querySelectorAll('.' + this.dropdownClass + '.' + this.expandedClass)).removeClass(this.expandedClass); }, show : function(e) { e.stopPropagation(); var dropdownMenu = angular.element($scope.utilities.findAncestor((e.target || e.srcElement), this.dropdownClass)); if (dropdownMenu.hasClass(this.expandedClass)) { this.removeClasses(); } else { this.removeClasses(); dropdownMenu.addClass(this.expandedClass); } } }; // Close elements if clicked outside angular.element(document).on('click', function() { $scope.utilities.dropdown.removeClasses(); }); } }); // -- START -- FETCH JSON DATA var jsonCache = {}; this.on('afterSearch', function($scope) { $scope.jsonCache = jsonCache; /* angular.forEach($scope.results, function(result) { // Additional logic for products that do not need to fetch data }); */ }); // -- END -- FETCH JSON DATA function addJsonData(result) { if (jsonCache[result.handle]) { // Update variables if json is available if (jsonCache[result.handle].quickview) { result.quickview = true; result.quickviewHtml = jsonCache[result.handle].quickview.replace(/ +/g, ' '); } } else if (!result.jsonLoading) { // Otherwise, fetch json if not in cache fetchJsonData(result); } } function fetchJsonData(result) { var getUrl = '/products/' + result.handle + '?view=quickview'; // Set jsonLoading to true result.jsonLoading = true; angular.injector(['ng']).invoke(function($http) { $http({ method : 'GET', url : getUrl }).success(function(data) { // Set jsonLoading to false result.jsonLoading = false; // Add json data to scope if (typeof data == 'object') { // Add json data to scope angular.extend(jsonCache, data); addJsonData(result); } else { jsonCache[result.handle] = {} console.log('invalid json on product ', result.handle); } $scope.$evalAsync(); }).error(function(err) { // No bueno :( }); }); } }; SearchSpring.Catalog.templates.promises.receive.resolve('');